/**
 * Created by woziji00226 on 2024-12-17 10:55:07.
 */
class GUI_ColorDemonGame_GamePlay_W26 extends GUI_15001 {
    private _config = {
        color: {
            allTime: 60,
            addTime: 0,
            lvMap: [2, 3, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9]
        },
        lvT: ["瞎子", "色盲", "色郎", "色狼", "色鬼", "色魔", "超级色魔", "变态色魔", "孤独求色"],
    }

    private _sp: number = 4;

    private _lv: number;

    private _posIndex: number;

    private _countdown: ColorDemon_Countdown_W26;

    constructor() {
        super();
        this._countdown = new ColorDemon_Countdown_W26(60000);

        this.GameStartUI.visible = true;
        this.GameOverUI.visible = false;


        //this.start();



        this.once(GameSprite.ON_DISPOSE, this, () => {
            this._countdown.clear();
            this._countdown = null;
        });


        this.startGameButton.on(EventObject.CLICK, this, this.start);

        this.restartGameButton.on(EventObject.CLICK, this, this.restart);

    }

    /**
     * 开始游戏
     */
    public start() {

        this.GameStartUI.visible = false;
        this.GameOverUI.visible = false;

        this.lv = 0;
        this._posIndex = null;
        this.visibleContainer.on(EventObject.CLICK, this, this.onClick);
        this._countdown.on(ColorDemon_Countdown_W26.EVENT_CURRENT_COUNTDOWN_CHANGE, this, this.onCountDownChange,);
        this._countdown.on(ColorDemon_Countdown_W26.EVENT_COUNTDOWN_COMPLETED, this, this.gameover);
        this._countdown.start();
        this.nextLv(0);
    }

    /**
     * 停止
     */
    public stop() {
        this._posIndex = null;
        this.visibleContainer.offAll();
        this._countdown.offAll();
        this._countdown.clear();
    }

    /**
     * 重新开始
     */
    public restart() {
        this.stop();
        this.start();
    }

    private gameover() {
        this.GameStartUI.visible = false;
        this.GameOverUI.visible = true;
        this.stop();
        this.refreshGameOverText();
    }


    /**
     * 倒计时更新时
     * @param countdown 
     */
    private onCountDownChange(countdown: number) {
        this.countdownLabel.text = (Math.floor(countdown / 1000)).toString();
    }


    /**
     * 按下
     */
    private onClick() {

        var mouseX = this.visibleContainer.mouseX;
        var mouseY = this.visibleContainer.mouseY;
        var offsetX = this.offsetX;
        var offsetY = this.offsetY;
        var cellSize = this.gridWdith;
        var spacing = this._sp;
        var size = this.size;

        var rows = size;
        var cols = size;

        var p = this.getCellFromMousePosition(mouseX, mouseY, offsetX, offsetY, cellSize, spacing, rows, cols);
        if (p == null) {
            //啥也没点中
            return;
        }

        //获取点中的索引
        var index = this.getIndexOfXY(p.x, p.y, size);

        if (this._posIndex === index) {
            //点中成功

            this.successClick();
        }
        else {
            this.failClick();
        }
    }


    private successClick() {
        this.nextLv(1);
    }

    private failClick() {
        this.gameover();
    }

    /**
     * 获取索引根据XY
     * @return [number] 
     */
    private getIndexOfXY(x, y, width): number {
        return y * width + x;
    }

    private getCellFromMousePosition(mouseX: number, mouseY: number, offsetX: number, offsetY: number, cellSize: number, spacing: number, rows: number, cols: number): { x: number, y: number } {
        // 计算格子的实际宽度（包括间距）
        const cellWithSpacing = cellSize + spacing;

        // 确定鼠标所在的可能的行和列
        let xIndex = Math.floor((mouseX - offsetX) / cellWithSpacing);
        let yIndex = Math.floor((mouseY - offsetY) / cellWithSpacing);

        // 检查索引是否越界
        if (xIndex < 0 || xIndex >= cols || yIndex < 0 || yIndex >= rows) {
            return null;
        }

        // 计算格子的实际位置
        const actualX = offsetX + xIndex * cellWithSpacing;
        const actualY = offsetY + yIndex * cellWithSpacing;

        // 检查鼠标是否在格子内部
        if (mouseX >= actualX && mouseX < actualX + cellSize &&
            mouseY >= actualY && mouseY < actualY + cellSize) {
            return { x: xIndex, y: yIndex };
        } else {
            return null; // 落在了格子之间的间距或超出格子范围
        }
    }

    /**
     * 下一级
     */
    private nextLv(lv = 1) {
        this.lv += lv;
        this._render();
    }

    /**
     * 获取数组最后一个数据
     * @param n 
     * @return [number] 
     */
    private _last(n: Array<any>): any {
        return n[n.length - 1];
    }

    /**
     * 渲染格子画面
     * @param size 大小
     * @param lv 等级
     */
    private _render() {
        //等级
        var lv = this.lv;
        //大小
        var size = this.size;
        //偏移 X
        var offsetX = this.offsetX;
        //偏移 Y
        var offsetY = this.offsetY;
        //格子宽度
        var gridWdith = this.gridWdith;
        //格子高度
        var gridHeight = this.gridHeight;
        //间隙
        var sp = this._sp;

        //长度
        var length = size * size;
        //宽度
        var width = size;

        var g = this._config.color.lvMap[lv] || this._last(this._config.color.lvMap);

        var difference = 15 * Math.max(9 - g, 1);
        difference = lv > 20 ? 10 : difference;
        difference = lv > 40 ? 8 : difference;
        difference = lv > 50 ? 5 : difference;

        //得到随机位置
        var posIndex = Math.floor(Math.random() * length);
        this._posIndex = posIndex;
        var color1 = this.getColor(255 - difference);
        var color2 = this.getLvColor(color1, difference);

        var baseColor = this.rgbToHex(color1[0], color1[1], color1[2]);
        var diColor = this.rgbToHex(color2[0], color2[1], color2[2]);

        var graphics = this.visibleContainer.graphics;
        graphics.clear();

        for (var i = 0; i < length; i++) {
            var pos = this.getXYFromIndex(i, width);
            graphics.drawRect(offsetX + pos.x * (gridWdith + sp), offsetX + pos.y * (gridHeight + sp), gridWdith, gridHeight, baseColor);
        }

        var pos = this.getXYFromIndex(posIndex, width);
        graphics.drawRect(offsetX + pos.x * (gridWdith + sp), offsetX + pos.y * (gridHeight + sp), gridWdith, gridHeight, diColor);
    }

    private refreshGameOverText() {
        debugger;
        var b = 15 > this.lv ? 0 : Math.ceil((this.lv - 15) / 5);
        var c = this._config.lvT[b] || this._last(this._config.lvT);
        this.lvLabel.text = `LV.${this.lv+1}`;
        this.lvLabel2.text = `${c}`;
    }

    /**
     * 根据索引获取xy
     * @param index 
     * @param width 
     */
    private getXYFromIndex(index: number, width: number) {
        // 计算行和列
        let y = Math.floor(index / width);
        let x = index % width;

        return { x, y };
    }


    /**
     * 255转16进制
     * @param r 
     * @param g 
     * @param b 
     * @return [string] 
     */
    private rgbToHex(r: number, g: number, b: number): string {
        // 确保每个值都在0-255之间
        r = Math.max(0, Math.min(255, r));
        g = Math.max(0, Math.min(255, g));
        b = Math.max(0, Math.min(255, b));

        // 将RGB值转换为十六进制并确保是两位数
        let hexR = r.toString(16).padStart(2, '0');
        let hexG = g.toString(16).padStart(2, '0');
        let hexB = b.toString(16).padStart(2, '0');

        // 返回完整的十六进制字符串
        return `#${hexR}${hexG}${hexB}`.toUpperCase();
    }


    /**
     * 得到一个随机的颜色 根据a值
     * @param a 
     * @return [Array] 
     */
    private getColor(a: number): Array<any> {
        var b = [Math.round(Math.random() * a), Math.round(Math.random() * a), Math.round(Math.random() * a)];
        return b;
    }

    /**
     * 获取相差的颜色
     * @param a 
     * @param difference 
     * @return [Array] 
     */
    private getLvColor(a: Array<number>, difference: number): Array<number> {
        var color = [a[0] + difference, a[1] + difference, a[2] + difference];
        return color;
    }

    private get gridWdith(): number {
        var gridWdith = Math.floor(this.visibleContainer.width / this.size) - this._sp;
        return gridWdith;
    }

    private get gridHeight(): number {
        var gridHeight = Math.floor(this.visibleContainer.height / this.size) - this._sp;
        return gridHeight;
    }

    private get offsetX(): number {
        var f = this.visibleContainer.width - ((this.gridWdith + this._sp) * this.size) + this._sp;
        var zx = f / 2;
        return zx;
    }

    private get offsetY(): number {
        var f2 = this.visibleContainer.height - ((this.gridHeight + this._sp) * this.size) + this._sp;
        var zy = f2 / 2;
        return zy;
    }

    private get size() {
        var size = this._config.color.lvMap[this._lv] || this._last(this._config.color.lvMap)
        return size;
    }


    private set lv(value) {
        this._lv = value;
        this.scoreLabel.text = `得分：` + this._lv.toString();
    }

    private get lv() {
        return this._lv;
    }
}